﻿using Gargoyle.Roton;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;

namespace Lyon
{
    static class ArgParser
    {
        /// <summary>
        /// Parses a command line argument.
        /// </summary>
        /// <param name="Argument"></param>
        public static bool Parse(string Argument)
        {
            string arg;
            bool argHandled = false;

            if(Argument.Length <= 1) return false;
            arg = Argument.Substring(1);

            switch(Argument.Substring(0, 1))
            {
                // verb
                case "-":
                    ParseVerb(arg);
                    argHandled = true;
                    break;
                // config override
                case "+":
                    ParseConfig(arg);
                    argHandled = true;
                    break;
            }

            return argHandled;
        }

        private static string SectionAlias(string key)
        {
            switch(key)
            {
                // Video aliases
                case "Font":        return "Video";
                case "Palette":     return "Video";

                // FAIL
                default:            return null;
            }
        }

        private static void ParseConfig(string arg)
        {
            // format: Section.Key=Value
            //         Key=Value (automatically puts the key/value in the Global section unless an alias exists)
            string[] keyValue = arg.Split('=');
            string[] sectionKey;
            string section, key, value;

            if(keyValue.Length != 2)
            {
                // invalid config string -- abort processing
                Console.WriteLine(String.Format("Invalid configuration line: {0}", arg));
                return;
            }

            if(keyValue[0].Contains("."))
            {
                sectionKey = keyValue[0].Split('.');
                section = sectionKey[0];
                key = sectionKey[1];
                value = keyValue[1];
            }
            else
            {
                key = keyValue[0];
                section = SectionAlias(key);
                value = keyValue[1];
            }

            ConfigManager.SetValue(section, key, value);
        }

        private static void ParseVerb(string arg)
        {
        }
    }

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] Args)
        {
            string renderer, filename;

            // load default configuration file
            using(StringReader defaultConfig = new StringReader(Properties.Resources.Default))
            {
                ConfigManager.LoadConfig(defaultConfig, false);
            }

            string configPath = String.Format("{0}/{1}", Application.StartupPath, "Lyon.cfg");
            if(File.Exists(configPath))
                ConfigManager.LoadConfig(configPath, true);

            renderer = ConfigManager.GetValue("Video", "Renderer", "GDI");

            // process command line arguments
            foreach(string arg in Args)
            {
                if(!ArgParser.Parse(arg))
                {
                    // not a valid argument -- check to see if it's a file
                    if(File.Exists(arg))
                        Common.WorldFilename = arg;
                }
            }

            decimal videoScale = Convert.ToDecimal(ConfigManager.GetValue("Video", "Scale", "1"));
            switch(renderer)
            {
                case "GDI":
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new WinFormGDI());
                    break;
                case "OpenGL":
                case "OpenGLTiled":
                    // GameWindows open centered by default, so pass the scale so that the window be positioned properly
                    OpenGLTiledWindow openGLTiled = new OpenGLTiledWindow(videoScale);
                    openGLTiled.Title = "Lyon";
                    openGLTiled.Run(71.2d, 71.2d);
                    break;
                case "OpenGLFB":
                    // GameWindows open centered by default, so pass the scale so that the window be positioned properly
                    OpenGLFBWindow openGLFB = new OpenGLFBWindow(videoScale);
                    openGLFB.Title = "Lyon";
                    openGLFB.Run(71.2d, 71.2d);
                    break;
                default:
                    MessageBox.Show(String.Format("Unsupported renderer specified ({0}).", renderer), "Lyon - Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
            }
        }
    }
}
